#include <linux/module.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
//#include <arch/arm/include/asm/uaccess.h>


#define TMR_DEV_NAME "tmr_dev"
static int tmr_major;
static int tmr_cls;

#define TMR_DELAY		(1000)
static struct timer_list mytmr;
static int tmr_cnt = 0;


static void tmr_func(unsigned long data)
{
	printk("[TMR]%s \n", __func__);

	mod_timer(&mytmr, jiffies+(TMR_DELAY/1));

	if(tmr_cnt++>10){
		del_timer_sync(&mytmr);
		printk("[TMR] del timer sync ...\n");
	}
}

static int tmr_open(struct inode *inode, struct file *file)
{

	printk("[DRV-OPEN] open file ok!\n");

	return 0;
}

static ssize_t tmr_read(struct file *file, char *user, size_t size,loff_t *loff)
{
	int rbuf[32];
	long int ret = 0;

	ret = copy_from_user(rbuf,user, size);

	printk("buf: %d\n", rbuf[0]);

	return 0;
}

static ssize_t tmr_write(struct file *file, const char *user, size_t size, loff_t *loff)
{

	int rbuf[32];
	long int ret;

	ret = copy_from_user(rbuf,user, size);

	printk("buf: %d\n", rbuf[0]);
	return 0;
}

static int tmr_release(struct inode *inode, struct file *file)
{

	return 0;
}

static struct file_operations tmr_ops ={
	.owner = THIS_MODULE,
	.open = tmr_open,
	.write = tmr_write,
	.read  = tmr_read,
	.release = tmr_release,
};


static int tmr_probe(struct platform_device * pdev)
{

	struct resource		*res;
	struct device * dev;
	
	printk("[TMR_DRV]  tmr_probe\n");

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

	
	#if 0
	printk("res.start = %x\n", res->start);
	printk("res.end = %x\n", res->end);
	printk("res.flags = %x\n", res->flags);
	#endif
	
#define	AUTO_MAJOR

#ifdef AUTO_MAJOR
#define major 0
#else
#define major 123
#endif
	tmr_major = register_chrdev(major, TMR_DEV_NAME, &tmr_ops);
	tmr_cls = class_create(THIS_MODULE, TMR_DEV_NAME);
	dev = device_create(tmr_cls, NULL, MKDEV(tmr_major, 0), NULL, "tmr_dev");


	
	init_timer(&mytmr);
	mytmr.function = tmr_func;
	mytmr.expires = jiffies + TMR_DELAY;
	mytmr.data = NULL;
	tmr_cnt = 0;
	add_timer(&mytmr);

	
	return 0;
}

static int  tmr_remove(struct platform_device *pdev)
{
	//printk("[TMR_DRV]  tmr_remove\n");

	device_destroy(tmr_cls, MKDEV(tmr_major, 0));
	class_destroy(tmr_cls);
	unregister_chrdev(tmr_major, "tmr_dev");

	return 0;
}
static void tmr_shutdown(struct platform_device *pdev)
{
	printk("[LED_DRV]  tmr_shutdown\n");
	return ;
}
static int tmr_suspend(struct platform_device *pdev, pm_message_t state)
{
	printk("[LED_DRV]  tmr_suspend\n");
	return 0;
}
static int tmr_resume(struct platform_device *pdev)
{
	printk("[LED_DRV]  tmr_resume\n");
	return 0;
}

static struct platform_driver tmr_drv = {
	.probe = tmr_probe,
	.remove  =  tmr_remove,
	.shutdown = tmr_shutdown,
	.suspend = tmr_suspend,
	.resume = tmr_resume,
	.driver = {
		.name = "tmr",
	},
	
	//static const struct platform_device_id *id_table;
};

static int tmr_drv_init(void)
{
	platform_driver_register(&tmr_drv );
	return 0;
}

static void tmr_drv_exit(void)
{
	platform_driver_unregister(&tmr_drv );
	return ;
}

module_init(tmr_drv_init);
module_exit(tmr_drv_exit);

MODULE_LICENSE("GPL");

